/***********************************************************************************
 * 文 件 名   : chaintable.cpp
 * 负 责 人   : 唐家雄
 * 创建日期   : 2018年10月25日
 * 文件描述   : 
 * 版权说明   : Copyright (c) 2008-2018   宁波方太厨具有限公司
 * 其    他   : 
 * 修改日志   : 
***********************************************************************************/
#include<stdio.h>
#include<malloc.h>
#include"chaintable.h"

CChainTable::CChainTable()
{
	mHead = (ChainTable *)malloc(sizeof(ChainTable));
	if(!mHead)
	{
		printf("Create Chain Table Error!\n");
		//exit(0);
	}
	mHead->prev = mHead;
	mHead->next = mHead;
	mCount = 0;
}

CChainTable::~CChainTable()
{
	ChainTable* newnode=mHead->next;
	ChainTable* tmpnode=NULL;
	while(newnode != mHead)
	{
		tmpnode = newnode;
		newnode = newnode->next;
		free(tmpnode);
		mCount--;
	}
	
	free(mHead);
	mCount = 0;
}

bool CChainTable::InsertByPathForward(unsigned int path, void* data)
{
	ChainTable* targetnode = GetNode(path);
	if(!targetnode || !data)return false;
	
	ChainTable *prevnode = targetnode->prev;
	ChainTable *newnode = (ChainTable *)malloc(sizeof(ChainTable));
	newnode->data = data;
	newnode->prev = targetnode->prev;
	newnode->next = targetnode;
	targetnode->prev = newnode;
	prevnode->next = newnode;
	mCount++;
	return true;
}

bool CChainTable::InsertByPathBehind(unsigned int path, void* data)
{
	ChainTable* targetnode = GetNode(path);
	if(!targetnode || !data)return false;
	
	ChainTable *nextnode = targetnode->next;
	ChainTable *newnode = (ChainTable *)malloc(sizeof(ChainTable));
	newnode->data = data;
	newnode->prev = targetnode;
	newnode->next = targetnode->next;
	targetnode->next = newnode;
	nextnode->prev = newnode;
	mCount++;
	return true;
}

bool CChainTable::InsertByDataForward(void* targetdata, void* data)
{
	ChainTable* newnode=mHead->next;
	int i = 0;
	while((i++) < mCount)
	{
		if(newnode->data == targetdata)
		{
			ChainTable *prevnode = newnode->prev;
			ChainTable *mynode = (ChainTable *)malloc(sizeof(ChainTable));
			mynode->data = data;
			mynode->prev = newnode->prev;
			mynode->next = newnode;
			newnode->prev = mynode;
			prevnode->next = mynode;
			mCount++;
		}
		newnode	= newnode->next;
	}
}

bool CChainTable::InsertByDataBehind(void* targetdata, void* data)
{
	ChainTable* newnode=mHead->next;
	int i = 0;
	while((i++) <= mCount)
	{
		if(newnode->data == targetdata)
		{
			ChainTable *nextnode = newnode->next;
			ChainTable *mynode = (ChainTable *)malloc(sizeof(ChainTable));
			mynode->data = data;
			mynode->prev = newnode;
			mynode->next = newnode->next;
			newnode->next = mynode;
			nextnode->prev = mynode;
			mCount++;
		}
		newnode	= newnode->next;
	}
}

int CChainTable::SearchData(void* targetdata)
{
	ChainTable* newnode=mHead->next;
	int i = 0;
	while((i++) <= mCount)
	{
		if(newnode->data == targetdata)
		{
			return i;
		}
		newnode	= newnode->next;
	}
	return -1;
}

bool CChainTable::DeleteDate(void* targetdata, bool isall)
{
	ChainTable* newnode=mHead->next;
	int i = 0;
	bool deletesuccess = false;
	while((i++) <= mCount)
	{
		if(newnode->data == targetdata)
		{
			ChainTable *nextnode = newnode->next;
			ChainTable *prevnode = newnode->prev;
			nextnode->prev = prevnode;
			prevnode->next = nextnode;
			ChainTable *nownode = newnode;
						
			if(!isall) 
			{
				free(newnode);
				mCount--;
				deletesuccess = true;
				break;
			}
			newnode	= newnode->next;
			free(nownode);
			mCount--;
			deletesuccess = true;
			continue;
		}
		newnode	= newnode->next;
	}
	return deletesuccess;
}

ChainTable* CChainTable::GetNode(unsigned int path)
{
	if(path > mCount)
	{
		printf("No such path!\n");
		return NULL;
	}
	int i = 0;
	ChainTable* newnode=mHead->next;
	while((i++) < path)
	{
		newnode	= newnode->next;
	}
	return newnode;
}
